﻿using SharpDepend.Architecture.Windows;
using SharpDepend.Classes.Threading;
using System.Collections.Generic;

namespace SharpDepend.Architecture.Core
{
    public abstract class BaseApplicationCore<TApplication, TApplicationCore>
        where TApplicationCore : BaseApplicationCore<TApplication, TApplicationCore>
        where TApplication : IBaseApplication
    {
        /// <summary>
        /// Get main application instance.
        /// </summary>
        public TApplication Application { get; private set; }

        /// <summary>
        /// Get thread dispatcher to handle Main Thread from other threads.
        /// </summary>
        public Dispatcher Dispatcher { get; private set; }

        /// <summary>
        /// Get thread pool instance.
        /// </summary>
        public ThreadPool ThreadPool { get; private set; }

        /// <summary>
        /// Get windows manager to handle UI windows.
        /// </summary>
        public WindowManager<TApplication, TApplicationCore> WindowManager { get; private set; }

        public BaseApplicationCore(TApplication application)
        {
            Application = application;

            WindowManager = new WindowManager<TApplication, TApplicationCore>(application);

            Dispatcher = new Dispatcher();
            ThreadPool = new ThreadPool();
        }

        /// <summary>
        /// Must be called just after the constructor.
        /// </summary>
        public void Initialize()
        {
            List<IWindowBase<TApplication>> windows = new List<IWindowBase<TApplication>>();
            (Application as IBaseApplication<TApplication, TApplicationCore>).LoadWindows(windows);
            foreach (var window in windows)
            {
                WindowManager.RegisterWindow(window);
            }

            Dispatcher.Start();
            ThreadPool.Start();

            OnInitialized();
        }

        protected abstract void OnInitialized();
    }
}
